/**
 * Copyright 2024-2024 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef FRAMEWORK_C_MM_HIAI_MODEL_MANAGER_H
#define FRAMEWORK_C_MM_HIAI_MODEL_MANAGER_H

#include "c/hiai_c_api_export.h"
#include "c/hiai_error_types.h"
#include "c/hcl/hiai_types.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 创建模型管理指针实例
 *
 * 本方法提供模型管理指针的创建，在模型加载、推理等操作前，需要调用。
 * 模型卸载后，不需要此指针实例时，调用{@link HIAI_MR_ModelManager_Destroy}进行销毁，否则将造成内存泄漏。
 *
 * @return 执行成功返回{@link HIAI_MR_ModelManager}指针实例，失败返回空指针
 * @see HIAI_MR_ModelManager_Destroy
 */
AICP_C_API_EXPORT HIAI_MR_ModelManager* HIAI_MR_ModelManager_Create(void);

/**
 * @brief 销毁模型管理指针实例
 *
 * 销毁通过{@link HIAI_MR_ModelManager_Create}创建的模型管理指针实例，传入指针的引用即可。若不调用，将造成内存泄漏。
 *
 * @param [in] manager {@link HIAI_MR_ModelManager}指针实例的引用，非空
 */
AICP_C_API_EXPORT void HIAI_MR_ModelManager_Destroy(HIAI_MR_ModelManager** manager);

/**
 * @brief 加载模型
 *
 * 此接口提供模型加载，通过加载选项{@link HIAI_MR_ModelInitOptions}的设置，可调整设备的频率。
 * 模型推理全部结束后，使用{@link HIAI_MR_ModelManager_Deinit}对模型进行卸载，降低进程常驻内存。
 *
 * @param [in] manager {@link HIAI_MR_ModelManager}指针实例，非空，否则返回失败
 * @param [in] options 加载参数{@link HIAI_MR_ModelInitOptions}指针实例，非空，否则返回失败
 * @param [in] builtModel {@link HIAI_MR_BuiltModel}指针实例，非空，否则返回失败
 * @param [in] listener {@link HIAI_MR_ModelManagerListener}指针实例，可选（同步推理时填入空指针），异步使能时需要设置
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 * @see HIAI_MR_ModelManager_Deinit
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelManager_Init(HIAI_MR_ModelManager* manager,
    const HIAI_MR_ModelInitOptions* options, const HIAI_MR_BuiltModel* builtModel,
    const HIAI_MR_ModelManagerListener* listener);

/**
 * @brief 模型同步推理
 *
 * 根据模型输入输出情况，申请tensor的内存，输入输出tensor的内存申请可使用{@link HIAI_MR_NDTensorBuffer}
 * 下的create方法，根据需求选择合适的接口。推理完成，用户不需使用tensor内存后，
 * 需调用{@link HiAI_NDTensorBufferDestroy}销毁申请的每一个tensor内存，否则将造成内存泄漏。
 *
 * @param [in] manager {@link HIAI_MR_ModelManager}指针实例，非空，否则返回失败
 * @param [in] input 模型输入的指针数组，非空，否则返回HIAI_INVALID_PARAM
 * @param [in] inputNum 模型输入的个数
 * @param [in] output 模型输出的指针数组，非空，否则返回HIAI_INVALID_PARAM
 * @param [in] outputNum 模型输出的个数
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelManager_Run(HIAI_MR_ModelManager* manager, HIAI_MR_NDTensorBuffer* input[],
    int32_t inputNum, HIAI_MR_NDTensorBuffer* output[], int32_t outputNum);

/**
 * @brief 卸载模型
 *
 * 模型不需推理计算后，需调用本接口进行模型的卸载，否则内存一直占用。
 *
 * @param [in] manager {@link HIAI_MR_ModelManager}指针实例，非空，否则返回失败
 * @return 函数执行结果状态。执行成功返回HIAI_SUCCESS；失败返回具体错误码，具体失败错误码可参考{@link HIAI_Status}
 */
AICP_C_API_EXPORT HIAI_Status HIAI_MR_ModelManager_Deinit(HIAI_MR_ModelManager* manager);

#ifdef __cplusplus
}
#endif

#endif // FRAMEWORK_C_MM_HIAI_MODEL_MANAGER_H
